<template>
  <el-dialog v-model="model" @close="closedDialog">
    <el-form ref="roleFormRef" :model="form" :rules="rules" label-width="100px">
      <el-row>
        <el-col :span="12">
          <el-form-item :label="$t('sysRole.code')" prop="roleCode">
            <el-input v-model="form.roleCode" maxlength="30" show-word-limit clearable
              :placeholder="$t('sysRole.codeRequired')" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item :label="$t('sysRole.name')" prop="roleName">
            <el-input v-model="form.roleName" clearable maxlength="30" show-word-limit
              :placeholder="$t('sysRole.nameRequired')" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item :label="$t('sysRole.parent')" prop="parentId">
            <el-tree-select v-model="form.parentId" :data="parentRoles" :render-after-expand="false" filterable
              clearable check-strictly style="width: 100%" :placeholder="$t('sysRole.parentRequired')"
              @change="selParentRole" />
          </el-form-item>
        </el-col>
      </el-row>
      <div class="positon_name">
        <el-row v-for="(i, index) in form.roleDuty" :key="index" style="width: 100%">
          <el-col :span="12">
            <el-form-item :label="$t('sysRole.mutualType')" :prop="`roleDuty.${index}.dutyType`">
              <jmash-select v-model="form.roleDuty[index].dutyType" clearable
                :placeholder="$t('sysRole.mutualTypeRequired')" :data="Dict.dutyTypeEnum.values" class="w-full" />
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item :label="$t('sysRole.mutualRole')" :prop="`roleDuty.${index}.roleId`">
              <el-tree-select v-model="form.roleDuty[index].roleId" :data="parentRoles" filterable clearable
                check-strictly :render-after-expand="false" style="width: 100%"
                :placeholder="$t('sysRole.mutualRoleRequired')" />
            </el-form-item>
          </el-col>
          <el-col v-if="index === 0" :span="1" class="position-center">
            <el-icon size="16" @click="domainsAdd">
              <CirclePlus />
            </el-icon>
          </el-col>
          <el-col v-if="index !== 0" :span="1" class="position-center">
            <el-icon size="16" @click="domainsRemove(index)">
              <Remove />
            </el-icon>
          </el-col>
        </el-row>
      </div>
      <el-row>
        <el-col :span="24">
          <el-form-item :label="$t('sysRole.operatePerm')" prop="permCodes">
            <el-select v-model="form.moduleId" :placeholder="$t('sysRole.moduleRequired')" clearable style="width: 100%"
              @change="selModule">
              <el-option v-for="item in moduleLists" :key="item.moduleId" :label="item.moduleName"
                :value="item.moduleId" />
            </el-select>
            &nbsp;&nbsp;&nbsp;
            <el-checkbox v-model="checkedAll" :indeterminate="isIndeterminate" @change="handleCheckedAll">
              {{ $t("sysRole.checkAll") }}/{{ $t("sysRole.checkNoAll") }}
            </el-checkbox>
            <el-table :data="permArray" row-key="resourceId" border :show-header="false"
              :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">             
              <el-table-column prop="resourceName" width="230" >
                <template #default="scope">
                  {{ scope.row.resourceName }}
                  <el-checkbox v-show="scope.row.perms.length > 0"
                    :name="scope.row.permPrefix" @change="handleCheckedRow">
                  </el-checkbox>
                </template>
              </el-table-column>
              <el-table-column>
                <template #default="scope">
                  <el-checkbox-group v-model="form.permCodes" @change="handleChecked">
                    <el-checkbox v-for="item in scope.row.perms" :key="item.permId" :value="item.permCode">
                      {{ item.permName }}
                    </el-checkbox>
                  </el-checkbox-group>
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item :label="$t('sysRole.description')" prop="description">
            <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 2 }" maxlength="200"
              show-word-limit :placeholder="$t('sysRole.descriptionRequired')" clearable />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closedDialog">{{ $t("common.cancel") }}</el-button>
        <el-button type="primary" @click="submitForm">
          {{ $t("common.confirm") }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, type PropType } from "vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
import { type FormInstance, type FormRules, ElMessage } from "element-plus";
import type { ResourcePerm } from "@/api/system/permission/types";
import type {
  RoleFormReq,
  RoleKey,
  RoleUpdateReq,
} from "@/api/system/role/types";
import { roleApi } from "@/api/system/role/index";
import { moduleApi } from "@/api/system/module/index";
import { permissionApi } from "@/api/system/permission/index";
import { Dict } from "@/api/system/index";
const model = defineModel<boolean>();
const roleFormRef = ref<FormInstance>();
let moduleLists = ref([] as any);
const parentRoles = ref();
const permArray = ref();
const checkedAll = ref(false);
const isIndeterminate = ref(false);
let operButtonCode = ref([] as string[]); // 所有的操作按钮code
let form: RoleFormReq = reactive({
  requestId: Math.random() * 10 + "",
  roleType: "role",
  updateMask: "roleCode,roleName,parentId,description",
  permCodes: [],
  roleDuty: [
    {
      roleId: "",
      dutyType: "",
    },
  ],
});
const codeExistValidate = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error(t("sysRole.codeRequired")));
  } else {
    const query = {
      roleCode: value,
      addFlag: !(form as RoleUpdateReq).roleId ? true : false,
      roleId: (form as RoleUpdateReq).roleId,
    };
    roleApi.existRole(query).then(({ data }) => {
      if (data === true) {
        callback(new Error(t("sysRole.codeExist")));
      } else {
        callback();
      }
    });
  }
};
const rules = reactive<FormRules<RoleFormReq>>({
  roleCode: [{ required: true, validator: codeExistValidate, trigger: "blur" }],
  roleName: [
    { required: true, message: t("sysRole.nameRequired"), trigger: "blur" },
  ],
});
const emits = defineEmits(["refresh"]);
const props = defineProps({
  entityKey: {
    type: Object as PropType<RoleKey>,
    default: () => { },
  },
});

function queryRoleData() {
  roleApi.treelistRole(props.entityKey?.roleId).then(({ data }) => {
    parentRoles.value = data.results;
  });
  moduleApi.moduleList().then(({ data }) => {
    moduleLists.value = data.results;
  });
}

// 根据上级角色查询所有关联角色
function selParentRole(value: string) {
  roleApi.roleId(value).then(({ data }) => {
    form.permCodes = data.permCodes;
  });
}

// 所属模块
function selModule() {
  queryPermData();
}

function queryPermData() {
  permissionApi.permlist(form.moduleId).then(({ data }) => {
    permArray.value = data.results;
    traverseTree(data.results);
  });
}

function domainsAdd() {
  if (form.roleDuty && form.roleDuty.length < 5)
    form.roleDuty?.push({
      roleId: "",
      dutyType: "",
    });
}

function domainsRemove(index: number) {
  form.roleDuty?.splice(index, 1);
}

// 递归遍历操作权限
function traverseTree(node: ResourcePerm[]) {
  for (let i = 0; i < node.length; i++) {
    for (let z = 0; z < node[i].perms.length; z++) {
      operButtonCode.value.push(node[i].perms[z].permCode);
    }
    traverseTree(node[i].children);
  }
}

// 全选
function handleCheckedAll(val: any) {
  form.permCodes = val ? operButtonCode.value : [];
  isIndeterminate.value = false;
}

// 全选
function handleCheckedRow(val: any, event: any) {
  let perm = event.target.name;
  if (val && form.permCodes) {
    const aPrefixCodes = operButtonCode.value.filter(code => code.startsWith(perm));
    form.permCodes = [...form.permCodes, ...aPrefixCodes];
  } else if (form.permCodes) {
    form.permCodes = form.permCodes.filter(code => !code.startsWith(perm));
  }
}

// 单独选
function handleChecked(val: any[]) {
  form.permCodes = val;
  const checkedNum = val.length;
  checkedAll.value = checkedNum === operButtonCode.value.length;
  isIndeterminate.value =
    checkedNum > 0 && checkedNum < operButtonCode.value.length;
}

const keys = Object.keys(props.entityKey);

const update = ref(keys.length >= 1);

if (update.value) {
  roleApi.findById(props.entityKey).then(({ data }) => {
    Object.assign(form, data);
    form.roleDuty =
      form.roleDutyModel && form.roleDutyModel.length > 0
        ? form.roleDutyModel
        : (form["roleDuty"] = [
          {
            roleId: "",
            dutyType: "",
          },
        ]);
    if (form.parentId === "00000000-0000-0000-0000-000000000000")
      form.parentId = "";
  });
}

const submitForm = async () => {
  await roleFormRef.value?.validate((valid) => {
    if (valid) {
      if (update.value) {
        roleApi.update(form as RoleUpdateReq).then((response) => {
          if (response.status === 200) {
            ElMessage({
              message: t("common.submitSuccess"),
              type: "success",
            });
            if (model.value) {
              model.value = false;
            }
            emits("refresh", response.status === 200);
          }
        });
      } else {
        roleApi.create(form).then((response) => {
          if (response.status === 200) {
            ElMessage({
              message: t("common.submitSuccess"),
              type: "success",
            });
            if (model.value) {
              model.value = false;
            }
            emits("refresh", response.status === 200);
          }
        });
      }
    }
  });
};

// 关闭弹框
function closedDialog() {
  if (model.value) {
    model.value = false;
  }
}

queryRoleData();
queryPermData();
</script>
<style scoped lang="scss">
.position-center {
  position: absolute;
  right: 0;
  top: 30%;
  transform: translate(0, -30%);
}

.plus-position {
  position: absolute;
  right: 0;
  top: 0;
  margin-top: 8px;
}
</style>
